package com.larno.larnosqliteexample.database.provider;

import android.content.ContentProvider;
import android.content.ContentResolver;
import android.content.ContentValues;
import android.content.UriMatcher;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteQueryBuilder;
import android.net.Uri;
import android.support.annotation.Nullable;
import android.text.TextUtils;

import com.larno.larnosqliteexample.database.TodoDatabaseHelper;
import com.larno.larnosqliteexample.database.tables.TodoTable;

import java.util.Arrays;
import java.util.HashSet;

/**
 * Created by sks on 2016/7/4.
 */
public class TodoContentProvider extends ContentProvider {
    public static final String CONTENT_ITEM_TYPE = ContentResolver.CURSOR_ITEM_BASE_TYPE + "/todo";

    private static final String AUTHORITY = "com.larno.larnosqliteexample.provider";
    private static final String BASE_PATH = "todo";
    private static final int TODOS = 10;
    private static final int TODO_ID = 20;

    public static final Uri CONTENT_URI = Uri.parse("content://" + AUTHORITY + "/" + BASE_PATH);



    private static final UriMatcher sURIMatcher = new UriMatcher(UriMatcher.NO_MATCH);

    static {
        sURIMatcher.addURI(AUTHORITY, BASE_PATH, TODOS);
        sURIMatcher.addURI(AUTHORITY, BASE_PATH + "/#", TODO_ID);
    }

    private TodoDatabaseHelper databaseHelper;

    @Override
    public boolean onCreate() {
        databaseHelper = new TodoDatabaseHelper(getContext());
        return true;
    }

    @Nullable
    @Override
    public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) {
        SQLiteQueryBuilder queryBuilder = new SQLiteQueryBuilder();
        checkColumns(projection);
        queryBuilder.setTables(TodoTable.TABLE_NAME);
        int uriType = sURIMatcher.match(uri);
        switch (uriType){
            case TODOS:
                break;
            case TODO_ID:
                queryBuilder.appendWhere(TodoTable.COLUMN_ID + "=" + uri.getLastPathSegment());
                break;
            default:
                throw  new IllegalArgumentException("Unknown URI: " + uri);
        }
        SQLiteDatabase database = databaseHelper.getReadableDatabase();
        Cursor cursor = queryBuilder.query(database, projection, selection, selectionArgs, null, null, sortOrder);
        cursor.setNotificationUri(getContext().getContentResolver(), uri);
        return cursor;
    }

    @Nullable
    @Override
    public String getType(Uri uri) {
        return null;
    }

    @Nullable
    @Override
    public Uri insert(Uri uri, ContentValues values) {
        int uriType = sURIMatcher.match(uri);
        SQLiteDatabase database = databaseHelper.getWritableDatabase();
        long id = 0;
        switch (uriType){
            case TODOS:
                id = database.insert(TodoTable.TABLE_NAME, null, values);
                break;
            default:
                throw  new IllegalArgumentException("Unknown URI: " + uri);
        }
        getContext().getContentResolver().notifyChange(uri, null);
        return Uri.parse(BASE_PATH + "/" + id);
    }

    @Override
    public int delete(Uri uri, String selection, String[] selectionArgs) {
        int uriType = sURIMatcher.match(uri);
        SQLiteDatabase database = databaseHelper.getWritableDatabase();
        int rowsDeleted = 0;
        switch (uriType){
            case TODOS:
                rowsDeleted = database.delete(TodoTable.TABLE_NAME, selection, selectionArgs);
                break;
            case TODO_ID:
                String id = uri.getLastPathSegment();
                if(TextUtils.isEmpty(selection)){
                    rowsDeleted = database.delete(TodoTable.TABLE_NAME, TodoTable.COLUMN_ID + "=" + id, null);
                }else {
                    rowsDeleted = database.delete(TodoTable.TABLE_NAME, TodoTable.COLUMN_ID + "=" + id + "AND" +selection, selectionArgs);
                }
                break;
            default:
                throw  new IllegalArgumentException("Unknown URI: " + uri);
        }
        getContext().getContentResolver().notifyChange(uri, null);
        return rowsDeleted;
    }

    @Override
    public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) {
        int uriType = sURIMatcher.match(uri);
        SQLiteDatabase database = databaseHelper.getWritableDatabase();
        int rowsUpdated = 0;
        switch (uriType){
            case TODOS:
                rowsUpdated = database.update(TodoTable.TABLE_NAME, values, selection, selectionArgs);
                break;
            case TODO_ID:
                String id = uri.getLastPathSegment();
                if(TextUtils.isEmpty(selection)){
                    rowsUpdated = database.update(TodoTable.TABLE_NAME, values, TodoTable.COLUMN_ID + "=" + id, null);
                }else {
                    rowsUpdated = database.update(TodoTable.TABLE_NAME, values, TodoTable.COLUMN_ID + "=" + id + "AND" +selection, selectionArgs);
                }
                break;
            default:
                throw  new IllegalArgumentException("Unknown URI: " + uri);
        }
        getContext().getContentResolver().notifyChange(uri, null);
        return rowsUpdated;
    }

    /**
     * 检查当前表中是否有要查询的列（column）
     * @param projection
     */
    private void checkColumns(String[] projection) {
        String[] available = {TodoTable.COLUMN_ID, TodoTable.COLUMN_CATEGORY, TodoTable.COLUMN_SUMMARY, TodoTable.COLUMN_DESCRIPTION};
        if(projection != null){
            HashSet<String> requestedColumns = new HashSet<>(Arrays.asList(projection));
            HashSet<String> availableColums = new HashSet<>(Arrays.asList(projection));
            if(!availableColums.containsAll(requestedColumns)){
                throw new IllegalArgumentException("Unknown columns in projection");
            }
        }
    }
}
